package com.example.service.impl;

import com.example.DTO.ArticleDTO;
import com.example.DTO.SuggestionDTO;
import com.example.DTO.UserReadingStatDTO;
import com.example.mapper.ArticleMapper;
import com.example.mapper.StatMapper;
import com.example.mapper.UserMapper;
import com.example.pojo.Article;
import com.example.pojo.PageBean;
import com.example.pojo.User;
import com.example.service.ArticleService;
import com.example.utils.ThreadLocalUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.DTO.DetailDTO;
import org.springframework.util.StringUtils;
import org.springframework.web.util.HtmlUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Pattern;

@Slf4j
@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StatMapper statMapper;

    private static final String HIGHLIGHT_START_TAG = "<span class='highlight'>";
    private static final String HIGHLIGHT_END_TAG = "</span>";
    @Override
    public void add(Article article) {
        //补充属性值
        article.setCreateTime(LocalDateTime.now());
        article.setUpdateTime(LocalDateTime.now());
        Claims claims = ThreadLocalUtil.get();
        Integer id = (Integer) claims.get("id");
        article.setCreateUser(id);
        if (article.getState().equals("草稿")){
            articleMapper.add(article);
        }
        if (article.getState().equals("发布")){
            article.setState("待审核");
            articleMapper.add(article);
        }

    }

    @Override
    public PageBean<Article> list(Integer pageNum, Integer pageSize, Integer categoryId, String state) {
        //1.创建PageHelper对象
        PageBean<Article> pageBean = new PageBean<>();

        //2.使用分页插件
        PageHelper.startPage(pageNum,pageSize);
        Claims claims = ThreadLocalUtil.get();
        Integer userId = (Integer) claims.get("id");
        //3.调用Mapper查询方法
        List<Article> list = articleMapper.list(userId,categoryId,state);
        Page<Article> p  = (Page<Article>) list;
        //把数据填充到PageBean对象中
        pageBean.setTotal(p.getTotal());
        //这里用来放真正的列表数组数据
        pageBean.setItems(p.getResult());
        return pageBean;
    }

    @Override
    public PageBean<ArticleDTO> listAll(Integer pageNum, Integer pageSize, Integer categoryId, String state) {
        // 使用分页插件
        PageHelper.startPage(pageNum, pageSize);
        Integer userId = null;

        // 查询原始数据（这里返回的是Page对象，实际上是Page<E>的子类）
        Page<Article> page = (Page<Article>) articleMapper.listAll(userId, categoryId, state);
        // 转换DTO
        List<ArticleDTO> list2 = new ArrayList<>();
        for (Article article : page) {
            ArticleDTO dto = new ArticleDTO();
            BeanUtils.copyProperties(article, dto);

            User user = userMapper.findById(article.getCreateUser());
            if(user != null){
                dto.setNickname(user.getNickname());
                dto.setUserPic(user.getUserPic());
            } else {
                dto.setNickname(null);
                dto.setUserPic(null);
            }
            list2.add(dto);
        }


        //先不做处理
        /*//按点赞数对list2进行降序排序
        list2.sort(Comparator.comparingInt(ArticleDTO::getLikes).reversed());
        //获取用户id
        Claims claims = ThreadLocalUtil.get();
        //如果没有用户登录，则什么也不做
        if (claims != null) {
            Integer uId = (Integer) claims.get("id");
            //获取用户阅读数据
            List<UserReadingStatDTO> statlist = statMapper.getUserReadingStat(uId);
            //根据阅读时长，对statlist进行排序阅读时长更长的对象排前面
            statlist.sort(Comparator.comparingInt(UserReadingStatDTO::getDuration).reversed());

            //根据用户的阅读统计数据数组statlist，用户阅读喜欢的种类（阅读更多的）应该排在最前面，对list2进行排序
            if (!statlist.isEmpty()) {
                // 获取用户最喜欢的分类（阅读时间最长）的前5个
                List<Integer> favoriteCategoryIds = new ArrayList<>();
                int count = 0;
                for (UserReadingStatDTO stat : statlist) {
                    if (count < 5) {
                        favoriteCategoryIds.add(stat.getCategoryId());
                        count++;
                    } else {
                        break;
                    }
                }

                // 对文章列表按照用户喜好排序：优先显示包含用户喜欢分类的文章
                list2.sort((a1, a2) -> {
                    boolean a1IsFavorite = favoriteCategoryIds.contains(a1.getCategoryId());
                    boolean a2IsFavorite = favoriteCategoryIds.contains(a2.getCategoryId());

                    // 如果两个都是喜欢的分类，或者都不是，就保持原有顺序（已经按点赞数排过序了）
                    if (a1IsFavorite == a2IsFavorite) {
                        return 0;
                    }
                    // 只有一个是喜欢的分类，喜欢的排前面
                    return a1IsFavorite ? -1 : 1;
                });
            }
        }*/

        PageBean<ArticleDTO> pageBean = new PageBean<>();
        pageBean.setTotal(page.getTotal());
        pageBean.setItems(list2);  // 这里使用转换后的DTO列表

        return pageBean;
    }

    @Override
    public List<SuggestionDTO> suggest(String keyword, Integer limit) {
        List<Article> list = articleMapper.searchByKeyword(keyword, limit);
        //转换DTO
        List<SuggestionDTO> list2 = new ArrayList<>();
        for (Article article : list) {
            SuggestionDTO dto = new SuggestionDTO();
            BeanUtils.copyProperties(article, dto);
            dto.setHighlightedTitle(highlightKeywords(dto.getTitle(), keyword));
            list2.add(dto);
        }
        return list2;
    }

    @Override
    public void addViewCount(Integer id) {
        articleMapper.addViewCount(id);
    }

    /**
     * 高亮关键词处理
     * @param text 原始文本
     * @param keyword 要高亮的关键词
     * @return 带高亮标记的文本
     */
    private String highlightKeywords(String text, String keyword) {
        if (StringUtils.isEmpty(keyword)) {
            return text;
        }

        // 转义HTML特殊字符防止XSS
        String escapedText = HtmlUtils.htmlEscape(text);
        String escapedKeyword = HtmlUtils.htmlEscape(keyword);

        // 不区分大小写的正则匹配
        String regex = "(?i)(" + Pattern.quote(escapedKeyword) + ")";

        // 替换匹配的关键词为高亮span
        return escapedText.replaceAll(regex, HIGHLIGHT_START_TAG + "$1" + HIGHLIGHT_END_TAG);
    }

    @Override
    public void delete(Integer id) {
        Claims claims = ThreadLocalUtil.get();
        Integer userId = (Integer) claims.get("id");
        articleMapper.delete(id,userId);
    }

    @Override
    public DetailDTO detail(Integer id) {
        Article article = new Article();
        article = articleMapper.detail(id);
        DetailDTO detailDTO = new DetailDTO();
        // Spring BeanUtils
        BeanUtils.copyProperties(article, detailDTO);// 注意参数顺序与Apache相反
        Integer ArticleId = article.getId();
        Claims claims = ThreadLocalUtil.get();
        //如果是未登录用户
        if (claims == null){
            detailDTO.setLiked(false);
            detailDTO.setCollected(false);
            return detailDTO;
        }
        Integer userid = (Integer) claims.get("id");
       // log.info("用户id为：" + userid);
        //查询用户是否点赞过文章
        if (articleMapper.ifliked(ArticleId,userid) != 0){
           detailDTO.setLiked(true);
        }
        else {
            detailDTO.setLiked(false);
        }
        //查询用户是否收藏过文章
        if (articleMapper.ifcollected(ArticleId,userid) != 0){
            detailDTO.setCollected(true);
        }
        else {
            detailDTO.setCollected(false);
        }
        return detailDTO;
    }

    @Override
    public void update(Article article) {
        Claims claims = ThreadLocalUtil.get();
        article.setCreateUser((Integer) claims.get("id"));
        article.setUpdateTime(LocalDateTime.now());
        articleMapper.update(article);
    }

    @Override
    public List<Article> blist() {
        List<Article> list = articleMapper.blist();
        return list;
    }

    @Override
    public List<ArticleDTO> selectAll(Article article) {
        article.setState("已发布");
        article.setCreateUser(null);
        List<Article> articleList = articleMapper.selectAll(article);
        int len = articleList.size();
        // 如果len不足10，补全10条数据
        if (len < 10) {
            int count = 10 - len;
            List<Article> articleList2 = articleMapper.clist(count);
            articleList.addAll(articleList2);
            //去掉id一样的数据
            for (int i = 0; i < len; i++) {
                for (int j = i + 1; j < len; j++) {
                    if (articleList.get(i).getId().equals(articleList.get(j).getId())) {
                        articleList.remove(j);
                        j--;
                        len--;
                    }
                }
            }
        }
        // 转换DTO
        List<ArticleDTO> list2 = new ArrayList<>();
        for (Article article1 : articleList) {
            ArticleDTO dto = new ArticleDTO();
            BeanUtils.copyProperties(article1, dto);
            User user = userMapper.findById(article1.getCreateUser());
            if(user != null){
                dto.setNickname(user.getNickname());
                dto.setUserPic(user.getUserPic());
            } else {
                dto.setNickname(null);
                dto.setUserPic(null);
            }
            list2.add(dto);
        }

        return list2;
    }

    @Override
    public List<Article> listByState(String state) {
        List<Article> list = articleMapper.listByState(state);
        return list;
    }

    @Override
    public void updateState(Article article) {
        articleMapper.updateState(article);
    }


}
